#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/objects.h>
#include <openssl/err.h>

// 辅助函数：以十六进制格式打印字节数组
void print_hex(const char *label, const uint8_t *data, size_t len) {
    printf("%s: ", label);
    for (size_t i = 0; i < len; i++) {
        printf("%02X", data[i]);
    }
    printf("\n");
}

int main() {
    int ret = 0;

    // 1. 生成 SM2 密钥对
    EC_KEY *key1 = NULL, *key2 = NULL;
    printf("生成 SM2 密钥对...\n");
    key1 = EC_KEY_new_by_curve_name(NID_sm2);
    key2 = EC_KEY_new_by_curve_name(NID_sm2);
    if (!key1 || !key2) {
        fprintf(stderr, "SM2 密钥生成失败\n");
        return EXIT_FAILURE;
    }
    printf("SM2 密钥生成成功。\n");

    // 获取公钥
    EC_POINT *pub_key1 = EC_KEY_get0_public_key(key1);
    EC_POINT *pub_key2 = EC_KEY_get0_public_key(key2);

    // 计算共享密钥
    uint8_t shared_key1[256];
    size_t shared_key1_len = sizeof(shared_key1);
    ret = ECDH_compute_key(shared_key1, sizeof(shared_key1), pub_key2, key1, NULL);
    if (ret == -1) {
        fprintf(stderr, "密钥协商失败\n");
        return EXIT_FAILURE;
    }

    // 打印共享密钥
    printf("共享密钥（客户端）: ");
    print_hex("", shared_key1, shared_key1_len);

    printf("共享密钥协商成功。\n");

    // 清理
    EC_KEY_free(key1);
    EC_KEY_free(key2);

    return EXIT_SUCCESS;
}
